//https://github.com/SheetJS/sheetjs
// https://www.cnblogs.com/liuxianan/p/js-excel.html
// npm install xlsx
import * as XLSX from "xlsx";
/**
 * 导出Excel的处理函数--针对table
 * @param {Array} headers: [{key: 'date', title: '日期'}, {key: 'name', title: '名称'}]
 * @param {Array} data   : [{date: '2019-05-31', name: 'megen.huang'}, {date: 'name', name: '小明'}]
 * @param {String} fileName: '导出结果.xlsx'
 * */
export function exportExcel(headers, data, fileName = '导出结果.xlsx') {
    return new Promise((resolve) => {
        const _headers = headers
            .map((item, i) => Object.assign({}, { key: item.key, title: item.title, position: String.fromCharCode(65 + i) + 1 }))
            .reduce((prev, next) => Object.assign({}, prev, { [next.position]: { key: next.key, v: next.title.toString() } }), {});

        const _data = data
            .map((item, i) => headers.map((key, j) => Object.assign({}, { content: item[key.key], position: String.fromCharCode(65 + j) + (i + 2) })))
            // 对刚才的结果进行降维处理（二维数组变成一维数组）
            .reduce((prev, next) => prev.concat(next))
            // 转换成 worksheet 需要的结构
            .reduce((prev, next) => Object.assign({}, prev, { [next.position]: { v: next.content.toString() } }), {});

        // 合并 headers 和 data
        const output = Object.assign({}, _headers, _data);
        // 获取所有单元格的位置
        const outputPos = Object.keys(output);
        // 计算出范围 ,["A1",..., "H2"]
        const ref = `${outputPos[0]}:${outputPos[outputPos.length - 1]}`;

        const getCol = (matrix, col) => {
            var column = [];
            for (var i = 0; i < matrix.length; i++) {
                column.push(matrix[i][col]);
            }
            return column;
        }
        // 构建 workbook 对象
        const wb = {
            SheetNames: ['mySheet'],
            Sheets: {
                mySheet: Object.assign(
                    {},
                    output,
                    {
                        '!ref': ref,
                        // eslint-disable-next-line
                        '!cols': headers.map(item => {
                            /*设置worksheet每列的最大宽度*/
                            let colWidth = 0;
                            const colList = getCol(data, item.key)
                            colList.sort((a, b) => {
                                return b.toString().length - a.toString().length;
                            });
                            if (colList[0] == null) {
                                colWidth = 100
                            }
                            // 选出标题或者内容最宽的一个
                            const val = (item.title.toString().length > colList[0].toString().length) ? item.title : colList[0]
                            /**
                             * 使用canvas
                             * @param {String} text 文本
                             * @param {String} font 字体 如 'normal 12px Arial'
                             */
                            const getTextWidth = (text, font = "normal 12px Arial") => {
                                const canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"))
                                const context = canvas.getContext("2d")
                                context.font = font
                                const metrics = context.measureText(text)
                                return parseInt(metrics.width) + 10;
                            }
                            colWidth = getTextWidth(val)
                            return { wpx: colWidth }
                        })
                    }
                )
            }
        };
        // 导出 Excel
        XLSX.writeFile(wb, fileName);
        resolve(output)
    });
}

/**
 * 读取本地Excel
 * @param {文件} file 
 * @param {表头字段值} headers 
 * @returns 
 */
export function getLocalExcel(file, headers) {
    return new Promise((resolve) => {
        var reader = new FileReader();
        reader.onload = (e) => {
            var outputs = []; //清空接收数据
            var data = e.target.result;
            var workbook = XLSX.read(data, { type: "binary" });
            // 转化成指定数组对象
            var sheetNames = workbook.SheetNames; // 工作表名称集合
            var worksheet = workbook.Sheets[sheetNames[0]]; // 这里我们只读取第一张sheet
            var table = XLSX.utils.sheet_to_json(worksheet);
            for (var i = 0; i < table.length; i++) {
                let item = {}
                for (let key in headers) {
                    item[key] = table[i][headers[key]]
                }
                outputs.push(item)
            }
            resolve(outputs)
        };
        reader.readAsBinaryString(file)
    });
}